package dream_scene

import (
	"go_server/game_server/api/service/bag"
	"go_server/game_server/api/service/build"
	"go_server/game_server/constants"
	"go_server/game_server/dao/count_down_dao"
	"go_server/game_server/dao/scene_info_dao"
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/event_manager"
	"go_server/game_server/event_manager/event_data/event_impl"
	"go_server/game_server/initializer/map_data_init"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/game_server/world_manager"
	"go_server/zinx/ziface"
	"go_server/zinx/znet"
	"gorm.io/datatypes"
)

type DreamSceneBattleApi struct {
	znet.BaseRouter
}

func (*DreamSceneBattleApi) Handle(request ziface.IRequest) {
	msg := &pb.DreamSceneBattleC2S{}
	if !util.PBParseRet(request, msg) {
		return
	}

	conn := request.GetConnection()
	roleId := ServiceObj.GetRoleId(request)

	if msg.SceneId <= 0 || msg.Win <= 0 {
		world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_PARAM_ERROR, nil)
		return
	}

	baseSceneInfo, ok := config_manager.GetStcTableLevelChapter_SheetLevelChapterById(msg.SceneId)
	if !ok {
		world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNFIND, nil)
		return
	}

	eventType := baseSceneInfo.EntType            // 战斗类型:1,建筑战斗;2,梦境战斗
	powerCost := baseSceneInfo.PowerCost          // 战斗消耗体力
	unlockBuildLev := baseSceneInfo.UnlockBulidLv // 当前关卡解锁建筑等级
	unlockStar := baseSceneInfo.UnlockStar        // 解锁下一关卡所需要的星级
	unlockLevel := baseSceneInfo.UnlockLevel      // 解锁下关的关卡id
	firstReward := baseSceneInfo.FirstReward      // 首次通关奖励
	sweepReward := baseSceneInfo.SweepReward      // 扫荡奖励

	prizeMap := make(map[int32]int32) // 战斗奖励

	// 如果是建筑战斗
	if eventType != DREAM_SCENE_EVENT_TYPE {
		row := count_down_dao.GetCountDownByRoleId(roleId, []string{"build_fight_scene_ids"})

		var update = true
		buildFightSceneIds := make([]int32, 0)

		if row != nil && row.BuildFightSceneIds != nil {
			buildFightSceneIds = row.BuildFightSceneIds
		}

		if len(buildFightSceneIds) > 0 {
			eventSet := util.NewSet[int32]()
			eventSet.AddValue(buildFightSceneIds)
			if !eventSet.Contains(msg.SceneId) { // 没有完成过
				buildFightSceneIds = append(buildFightSceneIds, msg.SceneId)
			} else {
				update = false
			}
		} else {
			buildFightSceneIds = append(buildFightSceneIds, msg.SceneId)
		}

		if len(firstReward) > 0 {
			for _, v := range firstReward {
				prizeMap[v.Value[0]] = v.Value[1]
			}
		}

		// 组装返回数据结构
		res := new(pb.DreamSceneBattleS2C)
		res.SceneId = msg.SceneId
		res.Win = msg.Win
		res.Star = msg.Star
		res.IsFirst = 1
		res.UnLockSceneId = 0
		res.ItemMap = prizeMap

		conn.SendBuffPBMsg(uint32(pb.ProtocolManager_DreamSceneBattle), res)

		if update {
			// 记录战斗状态
			defer func() {
				countDown := count_down_dao.CountDown{
					RoleId:             roleId,
					BuildFightSceneIds: buildFightSceneIds,
				}
				count_down_dao.UpdateCountDown(&countDown, []string{"build_fight_scene_ids"})
			}()


			if msg.SceneId != DREAM_SCENE_REGISTER_SCENE_Id {
				// 发送战斗奖励
				bag.AddItemBatch(roleId, prizeMap)

				baseMapBuildInfo := config_manager.GetTableMap3DConfigSheetBuildConfigBySceneId(msg.SceneId)
				if baseMapBuildInfo != nil && baseMapBuildInfo.Id > 0 {
					go build.UpdateBuildClickType(roleId, map_data_init.InitMapID, baseMapBuildInfo.Id)
				}
			}
		}
	} else {
		// 判断体力是否足够
		hadPowerNum := bag.GetItemNum(roleId, DREAM_SCENE_POWER_ID)
		if hadPowerNum < powerCost {
			world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_NOT_ENOUGH_POWER, nil)
			return
		}

		buildLevel := build.GetBuildLv(roleId, map_data_init.InitMapID, constants.DREAM_SCENE_BUILD_ID, constants.RESOURCE_BUILD_CFG_ID) // 获取梦境关卡建筑等级
		if buildLevel < unlockBuildLev {
			world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_NOT_ENOUGH_POWER, nil)
			return
		}

		row := scene_info_dao.GetSceneByRoleId(roleId, []string{"scene_info"})
		if row == nil {
			world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNINIT, nil)
			return
		}

		tmpMap := make(map[int32][]int32)
		if row.SceneInfo.Data() != nil {
			tmpMap = row.SceneInfo.Data()
		}

		sceneInfo, ok := tmpMap[msg.SceneId]
		if !ok {
			world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNLOCK, nil)
			return
		}

		isFirst := sceneInfo[1]   //是否已完成首通：0,未完成;1,已完成
		totalStar := sceneInfo[2] //当前关卡累计星级

		var resIsFirst int32 = 0    // 默认返回 非首通
		var unLockSceneId int32 = 0 // 解锁下一关关卡id

		// 如果是首通,或者当前关卡历史累计星级 未达上限 且 战斗获得星级 > 0
		if isFirst <= 0 || (totalStar < unlockStar && msg.Star > 0) {
			// 首通
			if isFirst <= 0 {
				for _, v := range firstReward {
					prizeMap[v.Value[0]] = v.Value[1]
				}

				resIsFirst = 1 // 是首通
			}

			if (totalStar + msg.Star) >= unlockStar { // 满足解锁下关的星级条件
				totalStar = unlockStar

				_, ok := tmpMap[unlockLevel]
				if !ok { // 如果下一个关未解锁，则解锁下一个关卡
					tmpMap[unlockLevel] = []int32{unlockLevel, 0, 0}
					unLockSceneId = unlockLevel
				}
			} else {
				totalStar = totalStar + msg.Star
			}

			sceneInfo[1] = 1         // 已完成首通
			sceneInfo[2] = totalStar // 当前关卡累计星级

			tmpMap[msg.SceneId] = sceneInfo

			upMap := make(map[string]any)
			upMap["scene_info"] = datatypes.NewJSONType(tmpMap)

			scene_info_dao.UpdateSceneByRoleId(roleId, &upMap) // 修改关卡状态
		}

		// 扫荡奖励
		for _, v := range sweepReward {
			_, ok := prizeMap[v.Value[0]]
			if !ok {
				prizeMap[v.Value[0]] = v.Value[1]
			} else {
				prizeMap[v.Value[0]] += v.Value[1]
			}
		}

		if unLockSceneId > 0 { // 如果解锁了下一关,判断下一关的建筑限制等级是否达标，如果不达标也返回 0(未解锁)
			nextBaseSceneInfo, ok := config_manager.GetStcTableLevelChapter_SheetLevelChapterById(unLockSceneId)
			if !ok { // 下一关关卡配置不存在
				world_manager.WorldMgrObj.SendClientErrMsg(roleId, request, pb.ErrorCodeManager_DREARM_SCENE_UNFIND, nil)
				return
			}

			// 未解锁
			if buildLevel < nextBaseSceneInfo.UnlockBulidLv {
				unLockSceneId = 0
			}
		}

		// 组装返回数据结构
		res := new(pb.DreamSceneBattleS2C)
		res.SceneId = msg.SceneId
		res.Win = msg.Win
		res.Star = totalStar
		res.IsFirst = resIsFirst
		res.UnLockSceneId = unLockSceneId
		res.ItemMap = prizeMap
		res.PowerNum = hadPowerNum - powerCost // 剩余体力值

		conn.SendBuffPBMsg(uint32(pb.ProtocolManager_DreamSceneBattle), res)

		bag.SubItemSingle(roleId, DREAM_SCENE_POWER_ID, powerCost) // 扣除体力
		bag.AddItemBatch(roleId, prizeMap)                         // 发送战斗奖励

		// 创建梦境战斗事件
		event_manager.EventManagerObj.FireEventData(event_impl.NewDreamSceneBattleEvent(conn, map[string]int32{
			"id":    msg.SceneId,
			"value": totalStar,
		}))
	}
}
